package com.market.web.validator;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.market.domain.Location;
import com.market.domain.OrderDetail;
import com.market.domain.Product;
import com.market.domain.User;
import com.market.manager.LocationManager;
import com.market.manager.ProductManager;
import com.market.manager.UserManager;
import com.market.web.model.UserModel;

@Component("validator")
@Scope("session")
public class Validator {

	@Autowired
	private UserManager userManager;
	@Autowired
	private ProductManager productManager;

	private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\."
			+ "[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*"
			+ "(\\.[A-Za-z]{2,})$";

	public void validateEmail(FacesContext arg0, UIComponent uiComponent,
			Object value) throws ValidatorException {
		Pattern pattern;
		Matcher matcher;
		pattern = Pattern.compile(EMAIL_PATTERN);
		matcher = pattern.matcher(value.toString());
		if (!matcher.matches()) {
			FacesMessage msg = new FacesMessage("E-mail validation failed.",
					"Invalid E-mail format.");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}

		Map<String, Object> parameters = uiComponent.getAttributes();
		User userFromView = (User) parameters.get("user");
		User userFromDB = userManager.fetchByEmail(value.toString());
		if (userFromDB != null && !(userFromView.equalsId(userFromDB))) {
			FacesMessage msg = new FacesMessage("E-mail validation failed.",
					"Email:" + value.toString()
							+ " has already been registered ");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}

	}

	public void validateTelephone(FacesContext arg0, UIComponent uiComponent,
			Object telephone) throws ValidatorException {

		Map<String, Object> parameters = uiComponent.getAttributes();
		User userFromView = (User) parameters.get("user");
		User userFromDB = userManager.fetchByTelephone(telephone.toString());
		
		if (userFromDB != null && !(userFromView.equalsId(userFromDB))) {
			FacesMessage msg = new FacesMessage(
					"Telephone number validation failed.", "Telephone:"
							+ telephone.toString()
							+ " has already been registered. ");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}
	}

	/**
	 * This method validate time that user input, The format should be HH:MM HH
	 * should be 0=<HH<=23 and MM should be 0<=MM<=59, or throw an exception.
	 * 
	 * @param arg0
	 * @param arg1
	 * @param time
	 * @throws ValidatorException
	 */

	public void validateTime(FacesContext arg0, UIComponent arg1, Object time)
			throws ValidatorException {
		try {
			int hour = Integer.parseInt(time.toString().split(":")[0]);
			int minute = Integer.parseInt(time.toString().split(":")[1]);
			if (hour < 0 || hour > 23) {
				FacesMessage msg = new FacesMessage("Time validation failed.",
						"Hour:" + time.toString() + " is not valid. ");
				msg.setSeverity(FacesMessage.SEVERITY_ERROR);
				throw new ValidatorException(msg);
			}
			if (minute < 0 || minute > 59) {
				FacesMessage msg = new FacesMessage("Time validation failed.",
						"Minute:" + time.toString() + " is not valid. ");
				msg.setSeverity(FacesMessage.SEVERITY_ERROR);
				throw new ValidatorException(msg);
			}

		} catch (Exception e) {
			FacesMessage msg = new FacesMessage("Time validation failed.",
					e.toString());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}

	}

	public void validateDropOffLocation(FacesContext arg0, UIComponent arg1,
			Object location) throws ValidatorException {
		if (location == null) {
			FacesMessage msg = new FacesMessage("Drop off location invalid.",
					"Drop off location :" + location.toString()
							+ " is not exist");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}

	}

	public void validateNotEmpty(FacesContext arg0, UIComponent arg1,
			Object value) throws ValidatorException {
		if (value == null || value.toString().isEmpty()) {
			FacesMessage msg = new FacesMessage("Empty input",
					"This field is required");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}
	}

	public void validateInventory(FacesContext context,
			UIComponent uiComponent, Object value) throws ValidatorException {
		Map<String, Object> parameters = uiComponent.getAttributes();
		OrderDetail orderDetail = (OrderDetail) parameters.get("orderDetail");
		Product product = orderDetail.getProduct();
		Integer inventory = productManager.fetchInventory(product.getId());

		if (inventory < (Integer) value) {
			FacesMessage msg = new FacesMessage("Exceed stock", inventory + " "
					+ product.getPriceUnitLabel() + " left now");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}
	}

}
